
package cn.jbolt.core.service;

import cn.jbolt.core.base.JBoltGlobalConfigKey;
import cn.jbolt.core.base.JBoltMsg;
import cn.jbolt.core.base.config.JBoltConfig;
import cn.jbolt.core.cache.JBoltGlobalConfigTypeCache;
import cn.jbolt.core.common.enums.JBoltGlobalConfigTypeBuiltInEnum;
import cn.jbolt.core.common.enums.JBoltSystemLogTargetType;
import cn.jbolt.core.consts.JBoltConst;
import cn.jbolt.core.db.sql.Sql;
import cn.jbolt.core.kit.JBoltHttpSchemeKit;
import cn.jbolt.core.kit.JBoltSaasTenantKit;
import cn.jbolt.core.kit.JBoltUserKit;
import cn.jbolt.core.model.GlobalConfig;
import cn.jbolt.core.model.GlobalConfigType;
import cn.jbolt.core.model.User;
import cn.jbolt.core.service.base.JBoltBaseService;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Okv;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;

import java.util.List;

/**
 * 全局配置 service
 *
 * @author 小木 qq:909854136
 * @version 创建时间：2018年12月25日 下午11:18:26
 */
public class JBoltGlobalConfigService extends JBoltBaseService<GlobalConfig> {
    private GlobalConfig dao = new GlobalConfig().dao();

    @Override
    protected GlobalConfig dao() {
        return dao;
    }
    @Inject
    private JBoltUserService userService;
    @Inject
    private JBoltGlobalConfigTypeService globalConfigTypeService;

    /**
     * 更新
     *
     * @param globalConfig
     * @return
     */
    public Ret update(GlobalConfig globalConfig) {
        if (globalConfig == null || notOk(globalConfig.getId()) || notOk(globalConfig.getTypeId())) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        GlobalConfig db = findById(globalConfig.getId());
        if (db == null) {
            return fail(JBoltMsg.DATA_NOT_EXIST);
        }
        if (!db.getBuiltIn()) {
            return fail("此参数非内置参数，不能调用此接口修改");
        }
        GlobalConfigType type = JBoltGlobalConfigTypeCache.me.get(globalConfig.getTypeId());
        if (type == null) {
            return fail("关联类型数据不存在");
        }
        if (notOk(db.getTypeId()) || db.getTypeId().longValue() != globalConfig.getTypeId().longValue()) {
            db.setTypeId(globalConfig.getTypeId());
            db.setTypeKey(type.getTypeKey());
        }
        db.setConfigValue(globalConfig.getConfigValue());
        boolean success = db.update();
        if (success) {
            refreshJBoltConfig(globalConfig.getConfigKey());
            // 增加日志
            addUpdateSystemLog(globalConfig.getId(), JBoltUserKit.getUserId(), globalConfig.getName());
        }
        return ret(success);
    }

    /**
     * 判断与MainConfig有关的配置 更新调用
     *
     * @param configKey
     */
    private void refreshJBoltConfig(String configKey) {
        switch (configKey) {
            case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_WRITER:
                JBoltConfig.configActionReportWriter();
                break;
            case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_LINE_NUMBER_ENABLE:
                JBoltConfig.configJBoltActionReportLineNumberEnable();
                break;
            case JBoltGlobalConfigKey.JBOLT_AUTO_CACHE_LOG:
                JBoltConfig.configJBoltAutoCacheLog();
                break;
            default:
                break;
        }
    }

    /**
     * 处理valueType=null的组件
     */
    private void processDatasIfValueTypeIsNull() {
        Sql sql = selectSql().isNull("value_type");
        List<GlobalConfig> configs = find(sql.toSql());
        if (isOk(configs)) {
            for (GlobalConfig config : configs) {
                switch (config.getConfigKey()) {
                    case JBoltGlobalConfigKey.WECHAT_MP_SERVER_DOMAIN:
                        config.setValueType(GlobalConfig.TYPE_STRING);
                        break;
                    case JBoltGlobalConfigKey.WECHAT_WXA_SERVER_DOMAIN:
                        config.setValueType(GlobalConfig.TYPE_STRING);
                        break;
                    case JBoltGlobalConfigKey.WECHAT_ASSETS_SERVER_DOMAIN:
                        config.setValueType(GlobalConfig.TYPE_STRING);
                        break;

                    case JBoltGlobalConfigKey.JBOLT_LOGIN_USE_CAPTURE:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;

                    case JBoltGlobalConfigKey.JBOLT_LOGIN_CAPTURE_TYPE:
                        config.setValueType(GlobalConfig.TYPE_STRING);
                        break;

                    case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_WRITER:
                        config.setValueType(GlobalConfig.TYPE_STRING);
                        break;
                    case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_LINE_NUMBER_ENABLE:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;
                    case JBoltGlobalConfigKey.JBOLT_AUTO_CACHE_LOG:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;

                    case JBoltGlobalConfigKey.SYSTEM_DEPT_ENABLE:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;
                    case JBoltGlobalConfigKey.SYSTEM_POST_ENABLE:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;
                    case JBoltGlobalConfigKey.SYSTEM_USER_EXTEND_ENABLE:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;

                    case JBoltGlobalConfigKey.JBOLT_PASSWORD_CHANGE_NOTICE_DAYS:
                        config.setValueType(GlobalConfig.TYPE_INT);
                        break;
                    case JBoltGlobalConfigKey.JBOLT_DICTIONARY_DELETE_ENABLE:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;
                    case JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_ENABLE:
                        config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                        break;
                    case JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_TOKEN:
                        config.setValueType(GlobalConfig.TYPE_STRING);
                        break;
                    default:
                        config.setValueType(GlobalConfig.TYPE_STRING);
                        break;
                }
            }
            batchUpdate(configs);
        }

    }

    /**
     * 检测和初始化配置
     */
    public void checkAndInit() {
        processDatasIfValueTypeIsNull();

        globalConfigTypeService.checkAndInitTypes();

        checkAndInitConfig(JBoltGlobalConfigKey.WECHAT_MP_SERVER_DOMAIN);
        checkAndInitConfig(JBoltGlobalConfigKey.WECHAT_WXA_SERVER_DOMAIN);
        checkAndInitConfig(JBoltGlobalConfigKey.WECHAT_ASSETS_SERVER_DOMAIN);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_LOGIN_USE_CAPTURE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_LOGIN_CAPTURE_TYPE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_WRITER);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_LINE_NUMBER_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_AUTO_CACHE_LOG);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_DEPT_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_POST_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_USER_EXTEND_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_PASSWORD_CHANGE_NOTICE_DAYS);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_DICTIONARY_DELETE_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_TOKEN);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_COPYRIGHT_COMPANY);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_COPYRIGHT_LINK);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_DOMAIN_PUT_ON_RECORD_LINK);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_DOMAIN_PUT_ON_RECORD_INFO);

    }

    private GlobalConfigType getConfigType(String configKey) {
        GlobalConfigType type = null;
        switch (configKey) {
            case JBoltGlobalConfigKey.WECHAT_MP_SERVER_DOMAIN:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.WECHAT_DEV.getValue());
                break;
            case JBoltGlobalConfigKey.WECHAT_WXA_SERVER_DOMAIN:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.WECHAT_DEV.getValue());
                break;
            case JBoltGlobalConfigKey.WECHAT_ASSETS_SERVER_DOMAIN:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.WECHAT_DEV.getValue());
                break;

            case JBoltGlobalConfigKey.JBOLT_LOGIN_USE_CAPTURE:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.ADMIN_LOGIN.getValue());
                break;

            case JBoltGlobalConfigKey.JBOLT_LOGIN_CAPTURE_TYPE:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.ADMIN_LOGIN.getValue());
                break;

            case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_WRITER:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_LINE_NUMBER_ENABLE:
                type=JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.JBOLT_AUTO_CACHE_LOG:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_CONFIG.getValue());
                break;

            case JBoltGlobalConfigKey.SYSTEM_DEPT_ENABLE:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.SYSTEM_POST_ENABLE:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.SYSTEM_USER_EXTEND_ENABLE:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_CONFIG.getValue());
                break;

            case JBoltGlobalConfigKey.JBOLT_PASSWORD_CHANGE_NOTICE_DAYS:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_SAFE_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.JBOLT_DICTIONARY_DELETE_ENABLE:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_SAFE_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_ENABLE:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_SAFE_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_TOKEN:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_SAFE_CONFIG.getValue());
                break;
            case JBoltGlobalConfigKey.SYSTEM_COPYRIGHT_COMPANY:
            case JBoltGlobalConfigKey.SYSTEM_COPYRIGHT_LINK:
            case JBoltGlobalConfigKey.JBOLT_DOMAIN_PUT_ON_RECORD_INFO:
            case JBoltGlobalConfigKey.JBOLT_DOMAIN_PUT_ON_RECORD_LINK:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_PUT_ON_RECORD.getValue());
                break;

            default:
                type = JBoltGlobalConfigTypeCache.me.getByKey(JBoltGlobalConfigTypeBuiltInEnum.SYS_CONFIG.getValue());
                break;
        }

        return type;
    }

    /**
     * 检查并初始化全局配置表数据
     *
     * @param configKey
     */
    public void checkAndInitConfig(String configKey) {
        GlobalConfig config = findFirst(Okv.by("config_key", configKey));
        GlobalConfigType type = getConfigType(configKey);
        if (config == null) {
            config = new GlobalConfig();
            config.setConfigKey(configKey);
            config.setBuiltIn(true);
            switch (configKey) {
                case JBoltGlobalConfigKey.WECHAT_MP_SERVER_DOMAIN:
                    config.setName("微信公众号_服务器配置_根URL");
                    config.setConfigValue(JBoltHttpSchemeKit.getFull() + JBoltConfig.DOMAIN + "/wechat/mp/msg");
                    config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
                case JBoltGlobalConfigKey.WECHAT_WXA_SERVER_DOMAIN:
                    config.setName("微信小程序_客服消息推送配置_根URL");
                    config.setConfigValue(JBoltHttpSchemeKit.getFull() + JBoltConfig.DOMAIN + "/wechat/ma/msg");
                    config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
                case JBoltGlobalConfigKey.WECHAT_ASSETS_SERVER_DOMAIN:
                    config.setName("微信_静态资源_根URL");
                    config.setConfigValue(JBoltHttpSchemeKit.getFull() + JBoltConfig.DOMAIN);
                    config.setValueType(GlobalConfig.TYPE_STRING);
                    break;

                case JBoltGlobalConfigKey.JBOLT_LOGIN_USE_CAPTURE:
                    config.setName("系统登录页面是否启用验证码");
                    config.setConfigValue("true");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    break;

                case JBoltGlobalConfigKey.JBOLT_LOGIN_CAPTURE_TYPE:
                    config.setName("系统登录页验证码类型");
                    config.setConfigValue(GlobalConfig.CAPTCHA_TYPE_DEFAULT);
                    config.setValueType(GlobalConfig.TYPE_STRING);
                    break;

                case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_WRITER:
                    config.setName("系统 Action Report输出方式");
                    config.setConfigValue("sysout");
                    config.setValueType(GlobalConfig.TYPE_STRING);
                    JBoltConfig.ACTION_REPORT_WRITER = "sysout";
                    break;
                case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_LINE_NUMBER_ENABLE:
                    config.setName("系统 Action Report输出准确行号");
                    config.setConfigValue(JBoltConfig.ACTION_REPORT_LINE_NUMBER_ENABLE+"");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    break;
                case JBoltGlobalConfigKey.JBOLT_AUTO_CACHE_LOG:
                    config.setName("系统自动缓存Debug日志");
                    config.setConfigValue("false");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    JBoltConfig.JBOLT_AUTO_CACHE_LOG = false;
                    break;

                case JBoltGlobalConfigKey.SYSTEM_DEPT_ENABLE:
                    config.setName("启用部门");
                    config.setConfigValue("false");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    break;
                case JBoltGlobalConfigKey.SYSTEM_POST_ENABLE:
                    config.setName("启用岗位");
                    config.setConfigValue("false");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    break;
                case JBoltGlobalConfigKey.SYSTEM_USER_EXTEND_ENABLE:
                    config.setName("启用用户信息扩展");
                    config.setConfigValue("false");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    break;

                case JBoltGlobalConfigKey.JBOLT_PASSWORD_CHANGE_NOTICE_DAYS:
                    config.setName("多久没改密码就提醒");
                    config.setConfigValue("0");
                    config.setValueType(GlobalConfig.TYPE_INT);
                    break;
                case JBoltGlobalConfigKey.JBOLT_DICTIONARY_DELETE_ENABLE:
                    config.setName("是否启用字典删除功能");
                    config.setConfigValue("false");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    break;
                case JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_ENABLE:
                    config.setName("是否启用JWT-APIUser-有效性检测机制");
                    config.setConfigValue(JBoltConst.JBOLT_DEFAULT_CHECK_JWT_API_USER_EFFECTIVE_ENABLE + "");
                    config.setValueType(GlobalConfig.TYPE_BOOLEAN);
                    break;
                case JBoltGlobalConfigKey.JBOLT_CHECK_JWT_API_USER_EFFECTIVE_TOKEN:
                    config.setName("JWT-APIUser-有效性检测因子");
                    config.setConfigValue(JBoltConst.JBOLT_DEFAULT_CHECK_JWT_API_USER_EFFECTIVE_TOKEN);
                    config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
                case JBoltGlobalConfigKey.SYSTEM_COPYRIGHT_COMPANY:
					config.setName("系统版权所有人");
					config.setConfigValue(JBoltConst.JBOLT_DEFAULT_SYSTEM_COPYRIGHT_COMPANY);
					config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
                case JBoltGlobalConfigKey.SYSTEM_COPYRIGHT_LINK:
					config.setName("系统版权所有人的网址链接");
					config.setConfigValue(JBoltConst.JBOLT_DEFAULT_SYSTEM_COPYRIGHT_LINK);
					config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
                case JBoltGlobalConfigKey.JBOLT_DOMAIN_PUT_ON_RECORD_INFO:
					config.setName("系统备案号");
					config.setConfigValue("");
					config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
                case JBoltGlobalConfigKey.JBOLT_DOMAIN_PUT_ON_RECORD_LINK:
					config.setName("系统备案号链接");
					config.setConfigValue(JBoltConst.JBOLT_DEFAULT_DOMAIN_PUT_ON_RECORD_LINK);
					config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
                default:
                    config.setValueType(GlobalConfig.TYPE_STRING);
                    break;
            }
            if (type != null) {
                config.setTypeKey(type.getTypeKey());
                config.setTypeId(type.getId());
            }
            Long userId = JBoltUserKit.getUserId();
            if (notOk(userId)) {
                User user = userService.getOneSystemAdmin();
                if (user != null) {
                    userId = user.getId();
                }
            }
            config.setUserId(userId);
            config.setUpdateUserId(userId);
            config.save();
        } else {
            boolean needUpdateValue = false;
            if (notOk(config.getConfigValue())) {
                switch (configKey) {
                    case JBoltGlobalConfigKey.WECHAT_MP_SERVER_DOMAIN:
                        config.setConfigValue(JBoltHttpSchemeKit.getFull() + JBoltConfig.DOMAIN + "/wechat/mp/msg");
                        break;
                    case JBoltGlobalConfigKey.WECHAT_WXA_SERVER_DOMAIN:
                        config.setConfigValue(JBoltHttpSchemeKit.getFull() + JBoltConfig.DOMAIN + "/wechat/ma/msg");
                        break;
                    case JBoltGlobalConfigKey.WECHAT_ASSETS_SERVER_DOMAIN:
                        config.setConfigValue(JBoltHttpSchemeKit.getFull() + JBoltConfig.DOMAIN);
                        break;

                    case JBoltGlobalConfigKey.JBOLT_LOGIN_USE_CAPTURE:
                        config.setConfigValue("true");
                        break;

                    case JBoltGlobalConfigKey.JBOLT_LOGIN_CAPTURE_TYPE:
                        config.setConfigValue(GlobalConfig.CAPTCHA_TYPE_DEFAULT);
                        break;

                    case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_WRITER:
                        config.setConfigValue("sysout");
                        JBoltConfig.ACTION_REPORT_WRITER = "sysout";
                        break;
                    case JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_LINE_NUMBER_ENABLE:
                        config.setConfigValue(JBoltConfig.ACTION_REPORT_LINE_NUMBER_ENABLE+"");
                        break;
                    case JBoltGlobalConfigKey.JBOLT_AUTO_CACHE_LOG:
                        config.setConfigValue("false");
                        JBoltConfig.JBOLT_AUTO_CACHE_LOG = false;
                        break;

                    case JBoltGlobalConfigKey.SYSTEM_DEPT_ENABLE:
                        config.setConfigValue("false");
                        break;
                    case JBoltGlobalConfigKey.SYSTEM_POST_ENABLE:
                        config.setConfigValue("false");
                        break;
                    case JBoltGlobalConfigKey.SYSTEM_USER_EXTEND_ENABLE:
                        config.setConfigValue("false");
                        break;
                    default:
                        break;
                }
            }
            boolean needTypeInfo = false;
            if ((config.getBuiltIn() == null || notOk(config.getTypeId()) || notOk(config.getTypeKey()))
                    && type != null) {
                config.setTypeKey(type.getTypeKey());
                config.setTypeId(type.getId());
                config.setBuiltIn(true);
                needTypeInfo = true;
            }

            if (needTypeInfo || needUpdateValue) {
                config.update();
            }
        }

    }

    /**
     * 根据configKey获取全局配置
     *
     * @param configKey
     * @return
     */
    public GlobalConfig getByConfigKey(String configKey) {
        return findFirst(Okv.by("config_key", configKey));
    }


    /**
     * 后台查询管理使用 获取对应条件数据List
     *
     * @param typeId
     * @param builtIn
     * @param keywords
     * @return
     */
    public List<GlobalConfig> getAdminList(Long typeId, Boolean builtIn, String keywords) {
        return find(selectSql().eq("type_id", typeId).eqBooleanToChar("built_in", builtIn).likeMulti(keywords, "name", "config_key", "config_value", "type_key"));
    }

    /**
     * 切换Boolean类型数据值
     *
     * @param id
     * @return
     */
    public Ret toggleBooleanValue(Long id) {
        if (notOk(id)) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        GlobalConfig config = findById(id);
        if (config == null) {
            return fail(JBoltMsg.DATA_NOT_EXIST);
        }
        if (config.getValueType() == null || !config.getValueType().equalsIgnoreCase(GlobalConfig.TYPE_BOOLEAN)) {
            return fail("数据类型非Boolean不能执行此操作");
        }
        boolean isTrue = Boolean.parseBoolean(config.getConfigValue());
        config.setConfigValue(isTrue ? "false" : "true");
        boolean success = config.update();
        return success ? success(config, JBoltMsg.SUCCESS) : fail();
    }

    /**
     * 检测类型存在性
     *
     * @param typeId
     * @param typeKey
     * @return
     */
    public boolean checkTypeInUse(Long typeId, String typeKey) {
        if (notOk(typeId) || notOk(typeKey)) {
            return false;
        }
        return exists(selectSql().eq("type_id", typeId).eq("type_key", typeKey));
    }

    /**
     * 更新TypeKey
     *
     * @param typeId
     * @param typekey
     */
    public void updateTypeKey(Long typeId, String typekey) {
        update(updateSql().set("type_key", typekey).eq("type_id", typeId));
    }

    /**
     * 根据TypeKey更新typeId
     *
     * @param typeKey
     */
    public void updateTypeId(String typeKey, Long typeId) {
        update(updateSql().set("type_id", typeId).eq("type_key", typeKey));
    }


    /**
     * 清空指定类型下的缓存
     * @param typeId
     * @return
     */
    public Ret clearCacheByType(Long typeId){
        if(notOk(typeId)){
            return fail(JBoltMsg.PARAM_ERROR+" 未指定清空缓存所需的参数类型");
        }
        clearCacheBySql(selectSql().eq(TYPE_ID, typeId));
        return SUCCESS;
    }


    /**
     * 清空重来
     *
     * @return
     */
    public Ret clearReset() {
        clearCache();
        globalConfigTypeService.clearCache();
        update(updateSql().set("type_id", null).set("config_value", null));
        checkAndInit();
        return SUCCESS;
    }

    /**
     * 更新
     *
     * @param globalConfig
     * @return
     */
    public Ret saveCustomConfig(GlobalConfig globalConfig) {
        if (globalConfig == null || isOk(globalConfig.getId()) || notOk(globalConfig.getConfigKey())
                || notOk(globalConfig.getTypeId())) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        GlobalConfigType type = JBoltGlobalConfigTypeCache.me.get(globalConfig.getTypeId());
        if (type == null) {
            return fail("关联类型数据不存在");
        }
        globalConfig.setTypeKey(type.getTypeKey());
        globalConfig.setBuiltIn(false);
        boolean success = globalConfig.save();
        if (success) {
            // 增加日志
            addSaveSystemLog(globalConfig.getId(), JBoltUserKit.getUserId(), globalConfig.getName());
        }
        return ret(success);
    }

    /**
     * 更新自定义参数
     *
     * @param globalConfig
     * @return
     */
    public Ret updateCustomConfig(GlobalConfig globalConfig) {
        if (globalConfig == null || notOk(globalConfig.getId()) || notOk(globalConfig.getConfigKey())
                || notOk(globalConfig.getTypeId())) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        GlobalConfig db = findById(globalConfig.getId());
        if (db == null) {
            return fail(JBoltMsg.DATA_NOT_EXIST);
        }
        GlobalConfigType type = JBoltGlobalConfigTypeCache.me.get(globalConfig.getTypeId());
        if (type == null) {
            return fail("关联类型数据不存在");
        }
        if (notOk(db.getTypeId()) || db.getTypeId().intValue() != globalConfig.getTypeId().intValue()) {
            globalConfig.setTypeKey(type.getTypeKey());
        }
        globalConfig.setBuiltIn(false);
        boolean success = globalConfig.update();
        if (success) {
            // 增加日志
            addUpdateSystemLog(globalConfig.getId(), JBoltUserKit.getUserId(), globalConfig.getName());
        }
        return ret(success);
    }

    /**
     * 删除自定义参数配置
     *
     * @param id
     * @return
     */
    public Ret deleteCustomConfig(Long id) {
        return deleteById(id, true);
    }

    @Override
    protected String afterDelete(GlobalConfig config, Kv kv) {
        addDeleteSystemLog(config.getId(), JBoltUserKit.getUserId(), config.getName());
        return null;
    }

    @Override
    public String checkCanDelete(GlobalConfig config, Kv kv) {
        if (config.getBuiltIn() != null && config.getBuiltIn()) {
            return "此参数为系统内置参数不可删除";
        }
        return null;
    }

    @Override
    protected int systemLogTargetType() {
        return JBoltSystemLogTargetType.GLOBAL_CONFIG.getValue();
    }

    /**
     * 初始化租户的全局配置参数
     *
     * @param tenantId
     * @param tenantName
     * @param tenantSn
     */
    public void initTenantGlobalConfigs(String tenantId, String tenantName, String tenantSn) {
        if (StrKit.hasBlank(tenantId, tenantName, tenantSn)) {
            throw new RuntimeException("租户初始化全局配置参数创建需要传入所有参数不为空");
        }
        LOG.debug("正在初始化租户:[" + tenantName + ":" + tenantSn + "]的全局参数配置.....");
        //模拟租户调用全局参数配置初始化
        JBoltSaasTenantKit.me.useById(tenantId).call(() -> checkAndInitTenantDatas(tenantName, tenantSn));
        LOG.debug("初始化租户:[" + tenantName + ":" + tenantSn + "]的全局参数配置 完成！");
    }

    private void checkAndInitTenantDatas(String tenantName, String tenantSn) {
        globalConfigTypeService.checkAndInitTypes();

        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_LOGIN_USE_CAPTURE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_LOGIN_CAPTURE_TYPE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_WRITER);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_ACTION_REPORT_LINE_NUMBER_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.JBOLT_AUTO_CACHE_LOG);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_DEPT_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_POST_ENABLE);
        checkAndInitConfig(JBoltGlobalConfigKey.SYSTEM_USER_EXTEND_ENABLE);
    }

}
